package com.yonyou.pmclouds.organization.controller;


import com.alibaba.dubbo.config.annotation.Reference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonyou.iuap.tenant.sdk.TenantCenter;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.organization.entity.OrgAndRoleVO;
import com.yonyou.pmclouds.organization.entity.OrgTenantInfo;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.entity.RoleDistributeVO;
import com.yonyou.pmclouds.organization.rmiitf.OrgAndRoleQuery;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationMaintain;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import com.yonyou.pmclouds.organization.rmiitf.RoleDistributeQuery;
import com.yonyou.pmclouds.outter.role.RoleInfoQuery;
import com.yonyou.pmclouds.outter.user.UserOperator;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.Serializable;
import java.util.*;

/**
 * 组织
 */
@RequestMapping({"/organization", "/mobile/organization"})
@RestController
public class OrganizationController {

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private OrganizationMaintain maintain;
    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private OrganizationQuery organizationQuery;

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private OrgAndRoleQuery roleQuery;
    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private RoleDistributeQuery roleDistributeQuery;
    @Autowired
    private RoleInfoQuery roleInfoQuery;


    @Autowired
    private UserOperator userOperator;

    private ObjectMapper objMapper = new ObjectMapper();

    public OrganizationController() {
        //忽略未识别字段
        objMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 提交保存
     */
    @RequestMapping(value = "/add")
    public void add(@RequestBody OrganizationVO[] organizationVOS) throws BusinessException {
        if (ArrayUtils.isEmpty(organizationVOS)) return;
        maintain.insertOrgs(organizationVOS);
    }


    /**
     * 添加角色
     */
    @RequestMapping(value = "/addRole")
    @ResponseBody
    public RoleDistributeVO[] addRole(@RequestParam("pkRoles[]") String[] pkRoles) throws BusinessException {
        if (ArrayUtils.isEmpty(pkRoles)) return new RoleDistributeVO[0];
        List<RoleDistributeVO> insertList = new ArrayList<>();
        for (String pkRole : pkRoles) {
            RoleDistributeVO vo = new RoleDistributeVO();
            vo.setPkRole(pkRole);
            vo.setPkTenant(RuntimeEnvironment.getTenantId());
            insertList.add(vo);
        }
        return maintain.insertRoles(insertList.toArray(new RoleDistributeVO[0]));
    }


    /**
     * 分配
     */
    @RequestMapping(value = "/distribute")
    public void distribute(@RequestBody DistributeParam distributeParam) throws BusinessException {
        if (distributeParam == null || distributeParam.getOrgAndRoleVOS() == null) return;

        maintain.update4Distribute(distributeParam.getOrgAndRoleVOS());
    }

    /**
     * 取消分配并删除对应角色
     */
    @RequestMapping(value = "/cancelDistribute")
    public void distribute(@RequestParam("pkRole") String pkRole) throws BusinessException {
        if (StringUtils.isEmpty(pkRole)) return;
        maintain.update4CancelDistribute(pkRole);
    }


    /**
     * 根据角色查询组织(区分已分配，待分配)
     */
    @RequestMapping(value = "/getOrgList")
    @ResponseBody
    public OrganizationVO getOrgList(@RequestParam("pkRole") String pkRole) throws BusinessException, IOException {
        if (StringUtils.isEmpty(pkRole)) return null;
        String pkTenant = RuntimeEnvironment.getTenantId();
        OrganizationVO[] orgs = organizationQuery.queryOrgList(pkTenant, pkRole);
        OrgTenantInfo tenant = objMapper.readValue(TenantCenter.getTenantById(pkTenant), OrgTenantInfo.class);
        OrganizationVO root = new OrganizationVO();
        root.setPkTenant(pkTenant);
        root.setIsDistributed(roleQuery.queryIsDistribute(pkTenant, new String[]{pkRole}));
        if (tenant != null && tenant.getTenant() != null) {
            root.setTenantName(tenant.getTenant().getTenantName());
            root.setTenantCode(tenant.getTenant().getTenantCode());
            root.setSname(tenant.getTenant().getTenantName());  //为了前台方便
            root.setScode(tenant.getTenant().getTenantCode());
        }
        root.setChildren(orgs);
        return root;
    }

    /**
     * 查询租户下的所有角色(区分已分配，待分配)
     */
    @RequestMapping(value = "/getRoleList")
    @ResponseBody
    public List<Map> getRoleList() throws BusinessException {

        List<Map> roleList = roleInfoQuery.queryRolesByTenant(RuntimeEnvironment.getTenantId());
        RoleDistributeVO[] roleDistributeVOS = roleDistributeQuery.queryRoleDistribute(RuntimeEnvironment.getTenantId()); //角色列表
        Set<String> recordRole = new HashSet<>();
        if (ArrayUtils.isNotEmpty(roleDistributeVOS)) {
            for (RoleDistributeVO vo : roleDistributeVOS) {
                if (vo != null) recordRole.add(vo.getPkRole());
            }
        }
        for (Map map : roleList) {
            if (map.get("roleId") != null && recordRole.contains(map.get("roleId"))) {
                map.put("isDistributed", true);
            } else {
                map.put("isDistributed", false);
            }
        }
        return roleList;
    }


    /**
     * 启用
     */
    @RequestMapping(value = "/enable")
    public void enable(OrganizationVO[] organizationVOS) throws BusinessException {
        if (ArrayUtils.isEmpty(organizationVOS)) {
            return;
        }
        maintain.update4Enable(organizationVOS);
    }

    /**
     * 禁用
     */
    @RequestMapping(value = "/disable")
    public void disable(OrganizationVO[] organizationVOS) throws BusinessException {
        if (ArrayUtils.isEmpty(organizationVOS)) {
            return;
        }
        List<Map> roleList = roleInfoQuery.queryRolesByTenant(RuntimeEnvironment.getTenantId());
        Set<String> recordRole = new HashSet<>();
        if (roleList != null) {
            for (Map map : roleList) {
                if (map.get("roleId") != null) recordRole.add((String) map.get("roleId"));
            }
        }
        maintain.update4Disable(organizationVOS, recordRole);
    }

}

@Data
class DistributeParam implements Serializable {

    private OrgAndRoleVO[] orgAndRoleVOS;
}
